/*-+-*****************************************************************************
 Copyright (C) 2009-2012 Oceanside Software Corporation (R)
 Dallas, Texas

 Author       : Jason T. Brower
 Purpose      : This file is part of a point-of-sale software package
                originally written for Table-Service Restaurants.
              
 Date         : July 8th of 2012
              
 History      : The application that this software file belongs to was 
                written over a 3-Year period.  The first version was written
                in C# .Net 3.5 using Windows Forms.  Being new to .Net at
                the time, I soon learned of Windows Presentation Foundation,
                liked the graphics capabilities and databinding so I
                migrated to WPF.  When the .Net 4.0 framework was released
                the application was migrated from 3.5 to 4.0. Now today,
                .Net 4.5 RC is out and I was already in process of migrating
                before I made this public.
                
Excuse Me     : Please excuse the coding style, it is not representative of
                my typical work.  During the three years I was under a very
                tight budget, constantly running out of funding and was 
                working 18 hour days hyped up on 5-Hour Energy.  The 
                design is not textbook.  It is monolythic because of
                previous issues I will not get into.  There are few comments
                in the code and the ones that are there may be incorrect.
                
What it is not: This is not the exact version that I took through PA-DSS 2.0
                nor is it the exact version running at my customer sites.
                I removed some details for security purposes including some
                encryption algorithms.  The reporting was removed because
                I was including a third party library that cannot be 
                published with this Open Source.
                
What it is    : This application has been running at high volume restaraunts
                for over a year.  It never freezes, crashes or does anything
                unexpected.  So long as it is built, installed and configured
                correctly, it is a strong system that we can all enhance.

Contact       : Please note that I can no longer work for free.  However, you
                can reach me at information@oceansidesw.com.                                                      

*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
#if _LOCALDB
  using Oceanside.LocalDB;
#else
using Oceanside.RemoteDB;
#endif
namespace Oceanside
{
    /// <summary>
    /// Interaction logic for PageLogin.xaml
    /// </summary>
    public partial class PageUserRolesImp : PageImpBaseClass
    {
        ComboBox comboBoxName;
        DbLinkedTextBox textBoxDisplayName;
        ComboBox comboBoxAssignedRoles;
        DbLinkedBoundUserRolesComboBox comboBoxJobCodes;
        DbLinkedBoundUserRolesComboBox comboBoxPayGrades;
        DbLinkedBoundUserRolesComboBox comboBoxAccessLevels;

        /// <summary>
        /// Constructor
        /// </summary>
        public PageUserRolesImp(UIElementCollection uielementsChild, ComboBox comboBoxName, DbLinkedTextBox textBoxDisplayName,
            ComboBox comboBoxAssignedRoles, DbLinkedBoundUserRolesComboBox comboBoxJobCodes, DbLinkedBoundUserRolesComboBox comboBoxPayGrades, DbLinkedBoundUserRolesComboBox comboBoxAccessLevels, GroupBox mainGroup)
        {
            this.ButtonNumber = "5";
            this.ButtonLabelText = "User Roles";

            mNewGroupIsDisabled = true;
            mDeleteGroupIsDisabled = true;
            mButtonNewEntityName = "New User Role";
            mButtonDeleteEntityName = "Delete User's Role";
            RegisterSaveMeGroupBoxes(null, mainGroup);
            this.comboBoxName = comboBoxName;
            this.textBoxDisplayName = textBoxDisplayName;
            this.comboBoxAssignedRoles = comboBoxAssignedRoles;
            this.comboBoxJobCodes = comboBoxJobCodes;
            this.comboBoxPayGrades = comboBoxPayGrades;
            this.comboBoxAccessLevels = comboBoxAccessLevels;

            comboBoxAssignedRoles.SelectionChanged += new SelectionChangedEventHandler(comboBoxAssignedRoles_SelectionChanged);
            ///Register the controls and lock the form.
            RegisterUiElementsList(uielementsChild);

            ///Register for the events.
            comboBoxName.SelectionChanged += new SelectionChangedEventHandler(comboBoxName_SelectionChanged_NOTHROW);

            ///Add all text boxes to the list.
            mTextBoxesList.Add(textBoxDisplayName);

            ///Add the combo boxes.
            ListofComboboxes.Add(comboBoxName);
            ListofComboboxes.Add(comboBoxAssignedRoles);

            mListOfControlsToDisableInNonEditMode.Add(comboBoxJobCodes);
            mListOfControlsToDisableInNonEditMode.Add(comboBoxPayGrades);
            mListOfControlsToDisableInNonEditMode.Add(comboBoxAccessLevels);
            mEntityAddDeleteLoggingEnabled = true;
        }

        override public void Navigating()
        {
            Context.Refresh(RefreshMode.StoreWins, Context.ROLES);
            base.Navigating();
        }

        void comboBoxAssignedRoles_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                ROLE role = comboBoxAssignedRoles.SelectedItem as ROLE;
                if (role != null)
                {
                    comboBoxAccessLevels.SelectedItem = role.ACCESS_LEVEL;
                    comboBoxJobCodes.SelectedItem = role.JOB_CODE;
                    comboBoxPayGrades.SelectedItem = role.PAYGRADE;
                }
            }
            catch (Exception ex)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PLACEHOLDER, ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void comboBoxName_SelectionChanged_NOTHROW(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                USER user = (sender as ComboBox).SelectedItem as USER;

                if (user != null)
                {
                    user.ROLES.Load();
                    var q = from ROLE in user.ROLES where ROLE.IsDeleted == false select ROLE;

                    if (q.Any())
                    {
                        comboBoxAssignedRoles.ItemsSource = q.ToList();
                    }
                    else
                    {
                        comboBoxAssignedRoles.ItemsSource = null;
                    }
                }
            }
            catch (System.Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGE_USERROLES_CBNAME_SEL_CHANGED, exc);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        override public List<EntityObject> GetEntityObjectSet()
        {
            try
            {
                USER user = comboBoxName.SelectedItem as USER;
                var q = from ROLE in user.ROLES where ROLE.IsDeleted == false select ROLE;
                if (q.Any())
                {
                    return new List<EntityObject>(q.ToList());
                }
                return null;
            }
            catch (Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PLACEHOLDER, exc);
            }
            return null;
        }

        public override bool SaveMe()
        {
            List<ROLE> databaseRoles;
            bool retval = false;
            try
            {
                if (VerifyFormEntries())
                {
                    USER user = comboBoxName.SelectedItem as USER;
                    ROLE role = comboBoxAssignedRoles.SelectedItem as ROLE;

                    if (user != null && role != null)
                    {
                        role.ACCESS_LEVEL = comboBoxAccessLevels.SelectedItem as ACCESS_LEVEL;
                        role.PAYGRADE = comboBoxPayGrades.SelectedItem as PAYGRADE;
                        role.JOB_CODE = comboBoxJobCodes.SelectedItem as JOB_CODE;
                        retval = true;
                    }

                    ///First pull a fresh copy of the data from the DB
                    using (DominicaEntities newContext = new DominicaEntities(DominicaEntities.GetEfConString()))
                    {
                        databaseRoles = newContext.ROLES.Include("PAYGRADE").Include("JOB_CODE").Include("ACCESS_LEVEL").ToList();
                    }
                    ///If any of the paygrades change, we need to mark the old one as deleted and make
                    ///a new one.  We then need to update all roles that use that paygrade to point
                    ///to the new ID.
                    if (databaseRoles != null && databaseRoles.Count != 0)
                    {
                        foreach (ROLE dbRole in databaseRoles)
                        {
                            bool isModified = false;

                            ROLE localRole = Context.ROLES.Where(r => r.Id == dbRole.Id).FirstOrDefault();


                            if (localRole != null)
                            {
                                if (localRole.PAYGRADE == null)
                                {
                                    return false;
                                }

                                if (localRole.PAYGRADE.Id != dbRole.PAYGRADE.Id)
                                {
                                    isModified = true;
                                }

                                ///If the object was modified we need to make a new object with the same values,
                                ///change the old one back to the way it was and 
                                ///and mark it as deleted so it is only used for historical data.
                                if (isModified)
                                {
                                    ///Create a new role object, set its values to the values for the
                                    ///object that was just changed, then add it to the database.
                                    ROLE newObject = new ROLE();
                                    newObject.JOB_CODE = localRole.JOB_CODE;
                                    newObject.ACCESS_LEVEL = localRole.ACCESS_LEVEL;
                                    newObject.PAYGRADE = localRole.PAYGRADE;
                                    newObject.Name = localRole.Name;
                                    newObject.UserId = localRole.UserId;
                                    Context.ROLES.AddObject(newObject);

                                    ///Reset the original objects values, mark it as deleted and
                                    ///save.
                                    localRole.PAYGRADE = Context.PAYGRADES.Where(r => r.Id == dbRole.PAYGRADE.Id).FirstOrDefault();
                                    localRole.JOB_CODE = Context.JOB_CODES.Where(r => r.Id == dbRole.JOB_CODE.Id).FirstOrDefault();
                                    localRole.ACCESS_LEVEL = Context.ACCESS_LEVELS.Where(r => r.Id == dbRole.ACCESS_LEVEL.Id).FirstOrDefault();
                                    localRole.IsDeleted = true;
                                    Context.SaveChanges();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
            return retval;
        }

        /// <summary>
        /// 
        /// </summary>
        public override void NewEntityClicked()
        {
            USER user = comboBoxName.SelectedItem as USER;

            if (user != null)
            {
                var q = from ROLE in user.ROLES where ROLE.IsDeleted == false select ROLE;
                if (q.Count() < Constants.CONST_MAX_ROLES_PER_USER)
                {
                    base.NewEntityClicked();
                }
                else
                {
                    System.Windows.MessageBox.Show("You can only add " +
                        Constants.CONST_MAX_ROLES_PER_USER + " roles per user.");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override EntityObject GetSelectedEntityObject()
        {
            ROLE selected = comboBoxAssignedRoles.SelectedItem as ROLE;
            return selected;
        }

        /// <summary>
        /// 
        /// </summary>
        public override void MarkEntityDeleted()
        {
            ROLE selected = comboBoxAssignedRoles.SelectedItem as ROLE;
            selected.IsDeleted = true;
        }

        override public void CancelNewEntityWasClicked()
        {
            USER user = comboBoxName.SelectedItem as USER;
            if (user != null)
            {
                var q = from ROLE in Context.ROLES where ROLE.Name != null && ROLE.Name.Equals("NewRoleName") select ROLE;
                if (q.Any())
                {
                    foreach (ROLE role in q)
                    {
                        role.IsDeleted = true;
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public override void UpdateUsersEntitySource()
        {
            USER user = comboBoxName.SelectedItem as USER;

            if (user != null)
            {
                user.ROLES.Load();
                var q = from ROLE in user.ROLES where ROLE.IsDeleted == false select ROLE;

                if (q.Count() != 0)
                {
                    comboBoxAssignedRoles.ItemsSource = q.ToList();
                }
                else
                {
                    comboBoxAssignedRoles.ItemsSource = null;
                }
            }

            DominicaEntities.UpdateUsernameComboBinding(comboBoxName, Context);
            DominicaEntities.UpdateJobCodesComboBinding(comboBoxJobCodes, Context);
            DominicaEntities.UpdateAccessLevelsComboBinding(comboBoxAccessLevels, Context);
            DominicaEntities.UpdatePayGradesComboBinding(comboBoxPayGrades, Context);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override EntityObject AddNewEntityObject()
        {
            ROLE role = null;

            ///If there are no roles, access rights or job codes created yet then the user cannot create a role.
            ///Pop an error message.
            if (!(comboBoxAccessLevels.HasItems && comboBoxPayGrades.HasItems && comboBoxJobCodes.HasItems))
            {
                System.Windows.MessageBox.Show("You must first create an access level(s) and job code(s) before you can create a user role.", "Error", MessageBoxButton.YesNo);
            }
            else
            {
                USER user = comboBoxName.SelectedItem as USER;

                var q = from ROLE in Context.ROLES where ROLE.Name.Equals("Not Assigned") select ROLE;

                if (q.Count() == 0)
                {
                    role = new ROLE();
                    role.Name = "Not Assigned";

                    if (comboBoxPayGrades.Items.Count != 0)
                    {
                        comboBoxPayGrades.SelectedItem = comboBoxPayGrades.Items[0];
                        role.PAYGRADE = comboBoxPayGrades.Items[0] as PAYGRADE;
                    }

                    if (comboBoxAccessLevels.Items.Count != 0)
                    {
                        comboBoxAccessLevels.SelectedItem = comboBoxAccessLevels.Items[0];
                        role.ACCESS_LEVEL = comboBoxAccessLevels.Items[0] as ACCESS_LEVEL;
                    }

                    if (comboBoxJobCodes.Items.Count != 0)
                    {
                        comboBoxJobCodes.SelectedItem = comboBoxJobCodes.Items[0];
                        role.JOB_CODE = comboBoxJobCodes.Items[0] as JOB_CODE;
                    }

                    user.ROLES.Add(role);
                }
                else
                {
                    role = q.First();

                    role.IsDeleted = false;

                    if (comboBoxPayGrades.Items.Count != 0)
                    {
                        comboBoxPayGrades.SelectedItem = comboBoxPayGrades.Items[0];
                        role.PAYGRADE = comboBoxPayGrades.Items[0] as PAYGRADE;
                    }

                    if (comboBoxAccessLevels.Items.Count != 0)
                    {
                        comboBoxAccessLevels.SelectedItem = comboBoxAccessLevels.Items[0];
                        role.ACCESS_LEVEL = comboBoxAccessLevels.Items[0] as ACCESS_LEVEL;
                    }

                    if (comboBoxJobCodes.Items.Count != 0)
                    {
                        comboBoxJobCodes.SelectedItem = comboBoxJobCodes.Items[0];
                        role.JOB_CODE = comboBoxJobCodes.Items[0] as JOB_CODE;
                    }

                    user.ROLES.Add(role);
                }
            }

            return role;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override ComboBox GetEntityComboBox()
        {
            return comboBoxAssignedRoles;
        }
    }
}
